package com.michael.demos.base.thread.juc;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 类功能描述:
 * <pre>
 * 		信号量使用 DEMO  底层由AQS实现
 * 		信号量主要用于两个目的:
 *      	1. 用于多个共享资源的互斥使用
 * 			2. 用于并发线程数的控制.
 * </pre>
 *
 * @author Michael
 * @version 1.0
 * @date 2020/8/12 10:28
 */
public class SemaphoreDemo {

	/** 设定3个车位 */
	private static final Semaphore PARKING_SPACE = new Semaphore(3);
	/** 初始化汽车 */
	private static final List<CarThread> CAR_THREADS = Arrays.asList(
			new CarThread(PARKING_SPACE, "汽车 " + 1 + " "),
			new CarThread(PARKING_SPACE, "汽车 " + 2 + " "),
			new CarThread(PARKING_SPACE, "汽车 " + 3 + " "),
			new CarThread(PARKING_SPACE, "汽车 " + 4 + " "),
			new CarThread(PARKING_SPACE, "汽车 " + 5 + " "),
			new CarThread(PARKING_SPACE, "汽车 " + 6 + " "),
			new CarThread(PARKING_SPACE, "汽车 " + 7 + " ")
	);

	public static void main(String[] args) throws InterruptedException {

		System.out.println("开始抢车位...");

		CAR_THREADS.forEach(Thread::start);
		for (CarThread carThread : CAR_THREADS) {
			carThread.join();
		}

		System.out.println("车位使用完成");
	}

}

class CarThread extends Thread {

	private final Semaphore parkingSpace;

	public CarThread(Semaphore parkingSpace, String threadName) {
		this.parkingSpace = parkingSpace;
		this.setName(threadName);
	}

	private int getRandomInt(int min, int max) {
		Random random = new Random();
		return min + random.nextInt((max - min) + 1);
	}

	@Override
	public void run() {
		try {
			// 抢车位
			parkingSpace.acquire();
			String name = Thread.currentThread().getName();
			System.out.println(name + "成功抢到车位");
			int randomInt = getRandomInt(1000, 5000);
			System.out.println(name + "需要占用车位时间为：" + randomInt);
			TimeUnit.MILLISECONDS.sleep(randomInt);
			System.out.println(name + "归还车位");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			// 让出车位
			parkingSpace.release();
		}
	}
}
